#!usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 25 de Nov de 2011

@author: Francisco do Ó
@number: 5202
'''

import csv #funcionalidades para ficheiros de formato csv
#imports para criar servidor local
import SimpleHTTPServer
import SocketServer
import threading #permite criação de threads

#Listas a serem utilizadas nas procuras específicas
specOne = []
specTwo = []
specThree = []


httpd = ''

'''
@param one_unique
@param one_total
Dadas estas duas listas como parâmetros de entrada efectua 
o tratamento dos dados relativos à primeira procura
'''
def query_one(one_unique, one_total):   
    #Cria uma lista de elementos únicos com todos os dados necessários à procura 
    create_list_unique(one_unique, one_total)  
    #Cria uma lista de elementos únicos com os estabelecimentos de ensino 
    fileName = "./lists/estabelecimentos.csv"
    unique_field_list(one_unique, 0 ,fileName)
    #Cria a lista com o número de professores por estabelecimento por ano
    fileName = "./lists/oneocur.csv"      
    occurrences(one_unique, one_total, fileName)  

'''
@param two_unique
@param two_total
Dadas estas duas listas como parâmetros de entrada efectua 
o tratamento dos dados relativos à segunda procura
'''
def query_two(two_unique, two_total):
    #Cria uma lista de elementos únicos com todos os dados necessários à procura 
    create_list_unique(two_unique, two_total)
    #Cria uma lista de elementos únicos com as categorias existentes
    fileName = "./lists/categorias.csv"
    unique_field_list(two_unique, 1, fileName)
    #Cria a lista com o número de professores por categoria por estabelecimento por ano
    fileName = "./lists/twoocur.csv" 
    occurrences(two_unique, two_total, fileName)  

'''
@param three_unique
@param three_total
Dadas estas duas listas como parâmetros de entrada efectua 
o tratamento dos dados relativos à terceira procura
'''
def query_three(three_unique, three_total):
    #Cria uma lista de elementos únicos com todos os dados necessários à procura 
    create_list_unique(three_unique, three_total)
    #Cria uma lista de elementos únicos com os graus existentes
    fileName = "./lists/graus.csv"
    unique_field_list(three_unique,1,fileName)
    #Cria a lista com o número de professores por grau por estabelecimento por ano
    fileName = "./lists/threeocur.csv" 
    occurrences(three_unique, three_total, fileName)  

'''
@param list_unique
@param list_total
Dada uma lista com a totalidade dos elementos este método cria uma lista de 
elementos únicos verificando a existência (ou não) dessa linha na lista a criar
caso não exista, a linha é adicionada
'''    
def create_list_unique(list_unique , list_total):
    control = False #Variavel de controlo
    #corre todas as linhas da lista total
    for t in range(0,len(list_total)):     
        #corre todas as linhas da lista unica
        for u in range(0,len(list_unique)):
            #se existir control = True
            if list_total[t] == list_unique[u]:
                control = True
                pass           
            pass
        #Se control = false a linha nao existe na lista a criar
        if control == False: 
            #adicionar a linha à lista
            list_unique.append(list_total[t])
            pass
        control = False
        pass
    return list_unique

'''
@param listR
@param index
@param fileName
Método que recebe uma lista, um índice de linha e o nome de um ficheiro. 
É lido o índice recebido de cada uma das linhas da lista, e retirados os elementos únicos. 
''' 
def unique_field_list(listR , index,fileName):
    oneWriter = csv.writer(open(fileName, "wb")) #escritor csv
    lista = []#lista de controlo
    #para cada linha da lista recebida
    for row in listR:
        #adicionar o elemento com o indice recebido
        lista.append(row[index])
        seen = set()#inicializa o set
        seen_add = seen.add#adiciona elemento ao set
    #adiciona o elemento à lista de elementos únicos se ainda nao existir    
    result = ([ x for x in lista if x not in seen and not seen_add(x)]) 
    #escreve os elementos únicos no ficheiro
    for element in result:
        oneWriter.writerow([element])   

'''
@param list_unique
@param list_total
@param fileName 
Corre cada linha da list_unique e compara-a a cada linha da list_total
obtendo assim o número de ocorrências. 
'''                
def occurrences(list_unique, list_total,fileName):
    occurrences = {}#dicionário que terá o número das ocorrências
    oneWriter = csv.writer(open(fileName, "wb"), delimiter=',')
    ocur = 0#nr de ocorrências
    #para cada linha da list_unique
    for i in range(0,len(list_unique)): 
        #para cada linha da lista toal        
        for j in range(0,len(list_total)): 
            #se o elemento já existe
            if list_unique[i] == list_total[j]:
                #incrementa o número de ocorrências 
                ocur = ocur + 1          
                pass 
            pass
        #adiciona linha com nr de ocorrências ao dicionário 
        occurrences[list_unique[i]]=['Numero de Professores:  ' + str(ocur)]
        ocur = 0          
        pass   
     
    for info, occur in occurrences.items():
        formated = info, '=>', occur
        oneWriter.writerows([formated])

#Threading
class MyHTTPServerThreaded(threading.Thread):
    pass
'''
Abre os ficheiros csv com as ocorrências de cada uma das procuras e reescreve-os 
em formato HTML utilizando o BaseHTTPServer e o SimpleHTTPServer para iniciar o servidor local
'''
def stats_to_html():
    #Dados do servidor http local a ser criado
    global httpd
    Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
    port = 8000
    server_address = ('', port)
    httpd = SocketServer.TCPServer(server_address, Handler)
    httpd.allow_reuse_address = True
    '''
    Método cedido pelo professor.
    Thread que faz o servidor local ser executado em paralelo com a aplicação
    evitando assim que este pare
    '''
    def fthread():
        try:
            httpd.serve_forever()
        except:
            print "OOPS Thread"
            pass
        pass
    th = MyHTTPServerThreaded(target=fthread)
   
    #aceder: http://127.0.0.1:8000
    f=open("index.html" , "w")
    f.write('<html>')
    f.write('<head><center><h1>Resultados das Procuras</h1></center></head>')
    f.write('<body>')
    f.write('<b>Numero de professores por estabelecimento, por ano: </b><br /><br />') 
    oneFile  = open('./lists/oneocur.csv', "rb")
    reader = csv.reader(oneFile)
    for row in reader:
        f.write(str(row))
        f.write('<br />')
        pass
    oneFile.close()
    f.write('<br />')
    f.write('<br />')
    f.write('<b>Numero de professores por estabelecimento, por categoria, por ano: </b><br /><br />') 
    twoFile  = open('./lists/twoocur.csv', "rb")
    reader = csv.reader(twoFile)
    for row in reader:
        f.write(str(row))
        f.write('<br />')
        pass
    oneFile.close()
    f.write('<br />')
    f.write('<br />')
    f.write('<b>Numero de professores por estabelecimento, por grau, por ano: </b><br /><br />') 
    threeFile  = open('./lists/threeocur.csv', "rb")
    reader = csv.reader(threeFile)
    for row in reader:
        f.write(str(row))
        f.write('<br />')
        pass
    oneFile.close()
    
    f.write('</body>')
    f.write('</html>')
    f.close()
     
    th.start()
    print "serving at port", port
    pass


'''
Método baseado no do professor
Para o servidor HTTP local
'''
def stopHTML(httpd): # wxGlade: MyFrame.<event_handler>
    httpd.shutdown() 
    del httpd
    print "o servidor local parou"
    pass


'''
@param nome_estab
Recebe o nome de um estabelecimento de ensino como parâmetro de entrada 
Procura o número de professores nesse estabelecimento, entre os anos 2000 e 2010
Devolve os resultados obtidos
'''
def SpecQueryOne(nome_estab):
    global specOne
    rowReader = csv.reader(open('./lists/one_total.csv' , 'rb') ,delimiter = ',') #leitor csv
    ocur = 0 
    estab = {} #dicionário que terá os resultados
    one_total=[] #lista com os dados totais da primeira procura
    for row in rowReader:
        one_total.append(row)      
        '''
        É necessario carregar o ficheiro navamente para uma lista porque comparar directamente
        do ficheiro provoca um comportamento estranho. 
        '''
    ocur = 0 #Número de ocorrências
    #De 2000 a 2010       
    for i in range (2000,2010+1):
        #Obter ocorrências
        for row in one_total:
            if str(row[0].decode('UTF-8')) == str(nome_estab) and str(row[1].decode('UTF-8')) == str(i):
                ocur = ocur + 1 
                pass
            pass
        #Adicionar linhas com o número de ocorrências
        estab[nome_estab] = ['Ano: ' + str(i) , 'Numero de Professores: '+ str(ocur)]
        for nome_estab, occurInfo in estab.items():
            formated = nome_estab, '=>', occurInfo
            specOne.append([formated])

        ocur = 0
        pass 
    return specOne

'''
@param nome_estab
@param category
Recebe o nome de um estabelecimento de ensino e uma categoria como parâmetros de entrada 
Procura o número de professores com essa categoria, nesse estabelecimento, entre os anos 2000 e 2010 
Devolve os resultados obtidos.
'''
def SpecQueryTwo(nome_estab , category):
    global specTwo
    rowReader = csv.reader(open('./lists/two_total.csv' , 'rb') ,delimiter = ',')#leitor csv
    ocur = 0 
    estab = {} #dicionário que terá os resultados
    two_total=[] #lista com os dados totais da primeira procura
    for row in rowReader:
        two_total.append(row)      
    ocur = 0 #Número de ocorrências
    #De 2000 a 2010             
    for i in range (2000,2010+1):
        #Obter ocorrências
        for row in two_total:
            if str(row[0].decode('UTF-8')) == str(nome_estab)\
             and str(row[1].decode('UTF-8')) == str(category)\
              and str(row[2].decode('UTF-8'))  == str(i):
                ocur = ocur + 1 
                pass
            pass
        #Adicionar linhas com o número de ocorrências
        estab[nome_estab] = ['Categoria: ' +str(category) ,'Ano: ' + str(i) , 'Numero de Professores: '+ str(ocur)]    
        for nome_estab, occurInfo in estab.items():
            formated = nome_estab, '=>', occurInfo
            specTwo.append([formated])
            
        ocur = 0
        pass 
    return specTwo

'''
@param nome_estab
@param degree
Recebe o nome de um estabelecimento de ensino e um grau como parâmetros de entrada
Procura o número de professores com esse grau, nesse estabelecimento, entre os anos 2000 e 2010
Devolve os resultados obtidos.
'''
def SpecQueryThree(nome_estab , degree):
    global specThree
    rowReader = csv.reader(open('./lists/three_total.csv' , 'rb') ,delimiter = ',')
    ocur = 0
    estab = {} #dicionário que terá os resultados
    three_total=[] #lista com os dados totais da primeira procura
    for row in rowReader:
        three_total.append(row)      
    ocur = 0 #Número de ocorrências
    #De 2000 a 2010      
    for i in range (2000,2010+1):
        #Obter ocorrências
        for row in three_total:
            if str(row[0].decode('UTF-8')) == str(nome_estab)\
             and  str(row[1].decode('UTF-8')) == str(degree)\
              and str(row[2].decode('UTF-8'))  == str(i):
                ocur = ocur + 1 
                pass
            pass
        #Adicionar linhas com o número de ocorrências
        estab[nome_estab] = ['Grau: ' +str(degree) ,'Ano: ' + str(i) , 'Numero de Professores: '+ str(ocur)]  
        for nome_estab, occurInfo in estab.items():
            formated = nome_estab, '=>', occurInfo
            specThree.append([formated])

        ocur = 0
        pass 
    return specTwo

    
class LoadFileIntoArray():
    #recebe como parametro o nome do ficheiro que se pretende carregar para o Array
    #array esse que e denominado de fileArray
    def __init__(self,fileName):
        self.fileArray = []
        self.fileName = fileName

    #a variavel imputFile recebe como parametro o nome do ficheiro que se pretende
    #carregar para o array contendo as linhas
    def loadList(self):
        imputFile = csv.reader(open(self.fileName,'rb'))
        for line in imputFile:
            self.fileArray.append(line)
            pass
        return self.fileArray
    
    
